import React from 'react';
import { Icon, Button, Row, Col } from 'antd'
import ReactDOM from 'react-dom'
import 'styles/components/guide.scss'
import { messages, deepCopy } from "share/common";
import closeGuide from 'components/method/closeGuide'
import tween from "components/method/tween";
import GuideImg from 'images/components/guide.png'
import arrowUp from 'images/components/arrow-up.png'
import arrowDown from 'images/components/arrow-down.png'
import arrowLeft from 'images/components/arrow-left.png'
import arrowRight from 'images/components/arrow-right.png'
/**
 * 引导组件
 * 配合components/method/wrapGuide用的，单独用没用
 *
 * add: 判断引导框有没有超出可视区域再挪来挪去的真的太麻烦了 把横纵相对位置都自定义了一下，
 * 麻烦开发者加入引导的时候自己先跑一下保证不会超出可视区域 19-02-27 陈行健
 */
class Guide extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      index: 0,
      style: {},
      iconConfig: {
        type: '',
        style: {}
      }
    };
    this.guideFixedStyle = {
      display: 'none',
      width: 369,
      height: 204
    };
    this.scrollDom = document.querySelector(".content-layout");
    this.lastStyle = {};
    this.callBackCount = 0;
  }

  componentDidMount(){
    this.setStyle();
    if(window.addEventListener) {
      window.addEventListener('resize', this.setStyle);
    } else {
      window.attachEvent('onresize', this.setStyle);
    }
  }

  componentWillUnmount() {
    if(window.addEventListener) {
      window.removeEventListener('resize', this.setStyle);
    } else {
      window.detachEvent('onresize', this.setStyle);
    }
  }

  //判断元素是否在浏览器可视区域内
  isInCurrentPage = DOMRect => {
    let innerWidth = document.body.scrollWidth || document.documentElement.scrollWidth;
    return DOMRect.top < window.innerHeight &&
      DOMRect.top > 0 &&
      DOMRect.left < innerWidth &&
      DOMRect.left > 0;
  };

  //获取当前滚动条高度
  getCurrentScrollTop = (scrollDom = this.scrollDom) => {
    if(scrollDom === window)
      return window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
    else
      return scrollDom.scrollTop
  };

  setScrollTop = (scrollDom = this.scrollDom, val) => {
    if(scrollDom === window) {
      document.body.scrollTop = val;
      document.documentElement.scrollTop = val;
    } else {
      scrollDom.scrollTop = val;
    }
  };

  scrollToTop = (changeTop) => {
    let startTime = new Date();
    let move = () => {
      let timeStamp = new Date();
      let time = timeStamp - startTime;
      let targetVal = Math.tween.Linear(time, this.getCurrentScrollTop(), changeTop, 800);
      this.setScrollTop(this.scrollDom, targetVal);
      if(time < 800) {
        requestAnimationFrame(move);
      }
    };
    move();
  };

  setStyle = () => {
    const { index } = this.state;
    const nowGuide = this.props.actions[index];
    this.callBackCount = 0; //重置回调次数
    let dom = ReactDOM.findDOMNode(nowGuide.ref);
    let pos = dom.getBoundingClientRect(); //被引导元素的DOMRect对象
    //如果元素不在浏览器可视区域内，先调整至可视区域，然后重新获取Rect对象
    if(!this.isInCurrentPage(pos)) {
      if(pos.top > window.innerHeight){
        this.scrollToTop(pos.top - window.innerHeight);
      } else if(pos.top < 0) {
        this.scrollToTop(pos.top);
      }
      setTimeout(() => {
        this.resetPos();
      }, 801);
    } else {
      this.resetPos();
    }
  };

  resetPos = () => {
    const { index } = this.state;
    const nowGuide = this.props.actions[index];
    let dom = ReactDOM.findDOMNode(nowGuide.ref);
    let pos = dom.getBoundingClientRect(); //被引导元素的DOMRect对象
    let guide = this.guideFixedStyle; //引导提示框的宽高对象
    let gap = 20; //提示框与被引导元素之间的间距
    let style = { display: 'block' };
    let iconConfig = {
      className: '',
      style: {}
    };
    switch(nowGuide.placement){
      case 'bottom':
        style.top = pos.top + pos.height + gap;
        iconConfig = {
          className: 'arrow-up',
          style: Object.assign({
            background: `url(${arrowUp})`
          }, nowGuide.arrowStyle)
        };
        break;
      case 'left':
        style.left = pos.left - guide.width - gap;
        iconConfig = {
          className: 'arrow-right',
          style: Object.assign({
            background: `url(${arrowRight})`
          }, nowGuide.arrowStyle)
        };
        break;
      case 'top':
        style.top = pos.top - guide.height - gap;
        iconConfig = {
          className: 'arrow-down',
          style: Object.assign({
            background: `url(${arrowDown})`
          }, nowGuide.arrowStyle)
        };
        break;
      case 'right':
        style.left = pos.left + pos.width + gap;
        iconConfig = {
          className: 'arrow-left',
          style: Object.assign({
            background: `url(${arrowLeft})`
          }, nowGuide.arrowStyle)
        };
    }

    //为了防止超出浏览器可视区域
    //bottom和top位置模式可以选择横向相对位置，默认为center
    if(nowGuide.placement === "bottom" || nowGuide.placement === "top")
      switch (nowGuide.inline){
        case 'start':
          style.left = pos.left;
          break;
        case 'center':
          style.left = pos.left - (guide.width - pos.width) / 2;
          break;
        case 'end':
          style.left =  pos.right - guide.width;
          break;
        default:
          style.left = pos.left - (guide.width - pos.width) / 2;
          break;
      }

    //为了防止超出浏览器可视区域
    //left和right位置模式可以选择纵向相对位置，默认为center
    if(nowGuide.placement === "left" || nowGuide.placement === "right")
      switch (nowGuide.block){
        case 'start':
          style.top = pos.top;
          break;
        case 'center':
          style.top = pos.top - (guide.height - pos.height) / 2;
          break;
        case 'end':
          style.top = pos.bottom - guide.height;
          break;
        default:
          style.top = pos.top - (guide.height - pos.height) / 2;
          break;
      }
    // let guideGrid = document.getElementById('guide-grid');
    // guideGrid.style.top = pos.top > window.innerHeight ? (window.innerHeight - pos.height - 36 + 'px') : (pos.top + 'px');
    // guideGrid.style.left = pos.left + window.pageXOffset + 'px';
    // guideGrid.style.height = pos.height + 'px';
    // guideGrid.style.width = pos.width + 'px';

    style.left += window.pageXOffset;
    if(nowGuide.dynamic) {
      let f = 0;
      if(style.left < 202){nowGuide.placement = "right"; f = 1; this.callBackCount++;}
      if(style.top < 0){nowGuide.placement = "bottom"; f = 1; this.callBackCount++;}
      if(style.left + guide.width > window.innerWidth){nowGuide.placement = "left"; f = 1; this.callBackCount++;}
      if(style.top + guide.height > window.innerHeight){nowGuide.placement = "top"; f = 1; this.callBackCount++;}
      if(f && this.callBackCount < 5) {this.resetPos(); return;}
    }

    if(window.ISIE9 && index) {
      tween(document.querySelector("#guide-helper-component"), this.lastStyle, style, 500);
      setTimeout(() => {
        this.setState({ style, iconConfig });
      },501)
    }else{
      this.setState({ style, iconConfig })
    }
  };

  handleOver = () => {
    let finishedGuide = localStorage.getItem('hly.guide');
    let key = this.props.guideKey;
    //结束引导后放入localStorage，防止下次再次引导
    if(finishedGuide && JSON.parse(finishedGuide)) {
      localStorage.setItem('hly.guide', JSON.stringify(JSON.parse(finishedGuide).concat(key)))
    } else {
      localStorage.setItem('hly.guide', JSON.stringify([key]))
    }
    closeGuide(this.props.guidType);
  };

  render() {
    const { actions } = this.props;
    const { index, style, iconConfig } = this.state;
    const action  = actions[index];
    return (
      <div className="guide" style={{ ...this.guideFixedStyle, ...style }} id="guide-helper-component">
        <div className="close-icon" onClick={this.handleOver}>
          <Icon type="close" />
        </div>
        {/*<Icon {...iconConfig}/>*/}
        <i {...iconConfig}/>
        <Row style={{height: "100%"}}>
          <Col span="10" style={{textAlign: "center", marginTop: "4px"}}><img src={GuideImg} /></Col>
          <Col span="14" style={{height: "100%"}}>
            <h3>{action.title}</h3>
            <span style={{whiteSpace: "pre-wrap"}}>{action.content}</span>
            <div style={{ textAlign: 'right' }} className="button-area">
              {actions.length > 1 && index !== actions.length - 1 && <Button
                type="primary"
                onClick={() => {
                  this.setState({ index: index + 1 }, this.setStyle)
                }}
                size="small"
                disabled={index === actions.length - 1}
              >
                {messages('common.next.one')/*下一条*/}
              </Button>}
              {index === actions.length - 1 && <Button
                onClick={this.handleOver}
                type="primary"
                size="small"
              >
                {messages('components.key704')/*我知道了*/}
              </Button>}
            </div>
          </Col>
        </Row>
      </div>
    );
  }
}

Guide.PropTypes = {
  style: React.PropTypes.object,
  actions: React.PropTypes.array,
  guideKey: React.PropTypes.string
};

Guide.defaultProps = {
  style: {}
};

export default Guide;
